package data;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Formatter;

import communication.MessageManager;
import environment.Main;

public class Logger {
	
	private static String FILENAME_DATA;
	private static String FILENAME_DEBUG = "debuglog.txt";
	private static FileWriter fw;
	private static BufferedWriter bw = null;
	private static PrintWriter dbgLog = null;
	
	private static int runs = 1;
	
	/**
	 * Logger class
	 * Opens a txt file to be written on.
	 * If a log file already exists, increment
	 * to the next available name. ie. log1.txt -> log2.txt
	 */
	public static void init()
	{	
		FILENAME_DATA = "datalog.txt";
		int i = 0;
		File file = new File(FILENAME_DATA);
		while(file.exists())
		{
			i++;
			FILENAME_DATA = "datalog" + i + ".txt";
			FILENAME_DEBUG = "debuglog" + i + ".txt";
			file = new File(FILENAME_DATA);
		}
		
		try {
			dbgLog = new PrintWriter(new BufferedWriter(new FileWriter(FILENAME_DEBUG)));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			dbgLog = null;
		}
	}
	
	/**
	 *  Static method to write the time it took to finish
	 *  one round into a predetermined filename.  
	 * @param time 
	 * @throws IOException
	 */
	public static void logTime(long time, long rounds) throws IOException
	{
		fw = new FileWriter(FILENAME_DATA, true);
		bw = new BufferedWriter(fw);
		Double timeInSec =  (double) time/1000;
		
		StringBuilder sb = new StringBuilder();
		Formatter f = new Formatter(sb);
		String format;
		
		if(runs == 1)
		{
			format = "%6s %4s %4s %6s %6s %6s %6s %6s %6s %7s %7s %7s %7s %9s %6s %7s %7s %7s %7s %9s %10s %10s%n";
			f.format(	format, 
						"ROUND", "BOX", "FAIL", "HELP", "NOTIFY", "IGNORE", "WINNER",
						"ARRIVE", "COST", "ALIVEQN", "LIVEANS", "DYING", "TOTAL", "STEPsB4",
						"GOTO", "ALIVEQN", "LIVEANS", "DYING", "TOTAL", "STEPsTX",
						"TIME(s)", "TIMESTEPs");
		}
		
		format = "%6d %4d %4d %6d %6d %6d %6d %6d %6d %7d %7d %7d %7d %9d %6d %7d %7d %7d %7d %9d %10.2f %10d";
		f.format(	format, 
				runs, Main.numberOfBoxInGoal, Main.robotsFailed, MessageManager.HELP_MESSAGE_SENT, MessageManager.NOTIFY_MESSAGE_SENT, 
				MessageManager.IGNORE_MESSAGE_SENT, MessageManager.WINNER_MESSAGE_SENT,
				MessageManager.ARRIVE_MESSAGE_SENT,	MessageManager.COST_MESSAGE_SENT, 
				MessageManager.ARE_YOU_ALIVE_B4_SENT, MessageManager.I_AM_ALIVE_B4_SENT, 
				MessageManager.I_AM_DYING_B4_SENT, MessageManager.getTotalCoordinationMsgBeforeTx(), Main.beforeTxRounds,
				MessageManager.FP_MESSAGE_SENT, 
				MessageManager.ARE_YOU_ALIVE_TX_SENT, MessageManager.I_AM_ALIVE_TX_SENT, 
				MessageManager.I_AM_DYING_TX_SENT, MessageManager.getTotalCoordinationMsgDuringTx(), Main.duringTxRounds,
				timeInSec, rounds);
		
		MessageManager.resetCount();
		runs++;
		
		bw.write(sb.toString());
		bw.newLine();		
	}
	
	/**
	 * TODO General log messages need to be written to a different file
	 * Use stdout for now
	 * @param s
	 */
	public static void log(String s)
	{
		if(dbgLog == null)
			return;
		//System.out.println(s);
		dbgLog.println(s);
	}
	
	/**
	 *  close/flush the filestream
	 */
	public static void closeLog()
	{
		try {
			if(bw != null) bw.close();
			if(dbgLog != null) dbgLog.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
